/*
  
  libc Wrapper for use by Fortran
  
  
  LICENSE AGREEMENT:
  
  You agree that we don't agree to anything.
  
  
  DISCLAIMER OF WARRANTIES:
  
  This software is provided to you "AS IS," and the authors and
  contributors disclaim any warranty or liability obligations to you
  of any kind, implied or express, including but not limited to the
  warranties of merchantability, fitness for a particular purpose,
  and non-infringement.
  
*/

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

//
#include <sys/types.h>
#include <unistd.h>

//
#include <sys/wait.h>
#include <signal.h>

//
#include <sys/sysctl.h>
#include <sys/user.h>

//
extern int * __error();
#define errno (* __error())

void *termproc;

void catch_SIGTERM(int signo);

void setup_sigterm_(long int ptermproc)
{
  struct sigaction act;
  termproc=(void*)ptermproc;
  memset(&act, 0, sizeof(act));
  act.sa_handler = catch_SIGTERM;
  sigemptyset(&act.sa_mask);
  act.sa_flags = SA_NOCLDSTOP | SA_RESTART;
  sigaction(SIGHUP, &act, NULL);
  sigaction(SIGINT, &act, NULL);
  sigaction(SIGALRM, &act, NULL);
  sigaction(SIGTERM, &act, NULL);
  sigaction(SIGXCPU, &act, NULL);
  sigaction(SIGXFSZ, &act, NULL);
  sigaction(SIGVTALRM, &act, NULL);
  sigaction(SIGPROF, &act, NULL);
  sigaction(SIGUSR1, &act, NULL);
  sigaction(SIGUSR2, &act, NULL);
}

void catch_SIGTERM(int signo)
{
  printf("\nchild pid=%d got signal %d\n",getpid(),signo);
  void (*p_termproc)(void)=termproc;
  p_termproc();
  exit(signo);
}

void errmess_(char *p, int l)
{
  char *c=p+l-1;
  while(l>0&&(*c==0x20||*c==0x09)){
    l--;
    c--;
  }
  for(int i=0; i<l; i++) putc(*(p++),stderr);
}

int csetenv_(char *n, char *v, int ov, int ln, int lv)
{
  while(ln>0&&(*n==0x20||*n==0x09)){
    ln--;
    n--;
  }
  if(ln<=0) return -1;
  while(lv>0&&(*v==0x20||*v==0x09)){
    lv--;
    v--;
  }
  if(lv<=0) return -1;
  char *pn = malloc(ln+1);
  char *pv = malloc(lv+1);
  memcpy(pn,n,ln);
  memcpy(pv,v,lv);
  pn[ln]='\0';
  pv[lv]='\0';
  int rc=setenv(pn,pv,ov);
  free(pn);
  free(pv);
  return rc;
}
int cunsetenv_(char *n, int ln)
{
  while(ln>0&&(*n==0x20||*n==0x09)){
    ln--;
    n--;
  }
  if(ln<=0) return -1;
  char *pn = malloc(ln+1);
  int rc = unsetenv(n);
  free(pn);
  return rc;
}

void pid2bin_(pid_t pid, long int pbuf)
{
	char pathname[PATH_MAX];
	int error, name[4];
	size_t len;
	name[0] = CTL_KERN;
	name[1] = KERN_PROC;
	name[2] = KERN_PROC_PATHNAME;
	name[3] = pid;
	len = sizeof(pathname);
	error = sysctl(name, 4, pathname, &len, NULL, 0);
	if (error < 0) return;
	if(len<=1) return;
	memcpy((char *)pbuf,&pathname,len-1);
}
